﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace NMigrate
{
	/// <summary>
	/// Handle config files, 
	/// *.Web.config script are templated and copied to DefaultWebSitePath.
	/// *.App.config script are templated and copied to DefaultAppPath.
	/// *.*.exe.config files are copied to there corresponding folder of ApplicationPaths.
	/// *.*.config files are copied to there corresponding website folder in WebsitePaths.
	/// </summary>
	public class ConfigFileHandler : FileHandler
	{
		public ConfigFileHandler()
		{
			ApplicationExePaths = new List<string>();
			WebsitePaths = new List<string>();
		}
		public string DefaultWebSitePath
		{
			get;
			set;
		}
		public string DefaultAppExePath
		{
			get;
			set;
		}

		public List<String> ApplicationExePaths
		{
			get;
			internal set;
		}

		public List<string> WebsitePaths
		{
			get;
			internal set;
		}

		public override string Extension
		{
			get
			{
				return "config";
			}
		}

		private void AssertPathExist(string path, string propertyName)
		{
			if(!Directory.Exists(path))
				throw new InvalidOperationException(path + " was specified for " + propertyName + " but this path does not exist");
		}
		public override void Execute(System.IO.FileInfo file, Configuration args)
		{
			var fileName = FileName.Parse(file, true);
			var defaultWebConfig = fileName.Name.Equals("web", StringComparison.InvariantCultureIgnoreCase);
			if(defaultWebConfig)
			{
				CopyToPath(file, fileName, DefaultWebSitePath, "DefaultWebSitePath");
				return;
			}
			var defaultAppConfig = fileName.Name.Equals("app", StringComparison.InvariantCultureIgnoreCase);
			if(defaultAppConfig)
			{
				CopyToPath(file, fileName, DefaultAppExePath == null ? null : new FileInfo(DefaultAppExePath).Directory.FullName, "DefaultAppPath");
				return;
			}

			if(fileName.Name.EndsWith(".exe"))
			{
				var pathToApp = ApplicationExePaths.FirstOrDefault(p => p.EndsWith(fileName.Name));
				if(pathToApp == null)
					throw new InvalidOperationException("no executable found in ApplicationExePaths for config file " + file.Name);
				var directory = new FileInfo(pathToApp).Directory;
				File.Copy(file.FullName, Path.Combine(directory.FullName, fileName.Name + "." + fileName.Extension),true);
				return;
			}


			var pathToSite = WebsitePaths.FirstOrDefault(p => p.EndsWith(fileName.Name));
			if(pathToSite == null)
				throw new InvalidOperationException("no website directory found in WebsitePaths for config file " + file.Name);
			var siteDirectory = new FileInfo(pathToSite).Directory;
			File.Copy(file.FullName, Path.Combine(siteDirectory.FullName, Path.Combine(pathToSite, "Web.config")), true);
			return;

		}

		private void CopyToPath(FileInfo file, FileName fileName, string path, string propertyName)
		{
			if(path == null)
				throw new InvalidOperationException(file.Name + " was found but no " + propertyName + " was specified");
			AssertPathExist(path, propertyName);
			File.Copy(file.FullName, Path.Combine(path, fileName.Name + "." + fileName.Extension), true);
		}

		public override bool IsTemplated(System.IO.FileInfo file)
		{
			return true;
		}
	}
}
